package com.xz.stu.server.service.impl;

import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.object.PageUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xz.stu.server.entity.*;
import com.xz.stu.server.mapper.CourseScheduleMapper;
import com.xz.stu.server.service.*;
import com.xz.stu.server.mapper.CourseselectionMapper;
import com.xz.stu.server.vo.courseSelection.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author 熊磊
* @description 针对表【school_courseselection(开设课程信息表)】的数据库操作Service实现
* @createDate 2025-03-04 09:12:38
*/
@Service
public class CourseSelectionServiceImpl extends ServiceImpl<CourseselectionMapper, CourseSelection>
    implements CourseSelectionService {
    @Resource
    private CourseService courseService;
    @Resource
    private DepartmentService departmentService;
    @Resource
    private TermServiceImpl termService;
    @Resource
    private ClassroomService classroomService;
    @Resource
    private TeacherService teacherService;
    @Resource
    private StudentService studentService;
    @Resource
    private StudentCourseService studentCourseService;
    @Resource
    private CourseselectionMapper courseselectionMapper;
    @Resource
    private CourseScheduleMapper courseScheduleMapper;
    @Resource
    private EnrollmentService enrollmentService;


    @Override
    public Long createCourseSelection(CourseSelectionCreateReqVO createReqVO) {
        CourseSelection courseSelection = BeanUtils.toBean(createReqVO, CourseSelection.class);
        //判断当前教师当前节次是否有课
        long count = this.count(new LambdaQueryWrapper<CourseSelection>()
                .eq(CourseSelection::getWeekday, createReqVO.getWeekday())
                .eq(CourseSelection::getClassPeriod, createReqVO.getClassPeriod())
                .eq(CourseSelection::getTermId, createReqVO.getTermId()));
        if (count > 0) {
            throw new ServiceException(new ErrorCode(100000000, "当前教室节次有课"));
        }
        this.save(courseSelection);
        return courseSelection.getId();
    }

    @Override
    public void updateCourseSelection(CourseSelectionUpdateReqVO updateReqVO) {
        CourseSelection courseSelection = BeanUtils.toBean(updateReqVO, CourseSelection.class);
        this.updateById(courseSelection);
    }

    @Override
    public void deleteCourseSelection(List<Long> id) {
        this.removeByIds(id);
    }

    @Override
    public CourseSelectionRespVO getCourseSelection(Long id) {
        Map<Long, String> courseMap = courseService.lambdaQuery()
                .list()
                .stream().collect(Collectors.toMap(Course::getId, Course::getCourseName));
        Map<Long, String> deptMap = departmentService.list().stream().collect(Collectors.toMap(Department::getId, Department::getDeptName));
        Map<Long, String> termMap = termService.list().stream().collect(Collectors.toMap(Term::getId, Term::getTermName));
        Map<Long, String> teacherMap = teacherService.lambdaQuery()
                .list().stream().collect(Collectors.toMap(Teacher::getId, Teacher::getName));
        Map<Long, String> classroomMap = classroomService.list().stream().collect(Collectors.toMap(Classroom::getId, Classroom::getClassroomName));
        CourseSelection courseSelection = this.getById(id);
        CourseSelectionRespVO courseSelectionRespVO = BeanUtils.toBean(courseSelection, CourseSelectionRespVO.class);
        courseSelectionRespVO.setCourseName(courseMap.get(courseSelection.getCourseId()));
        courseSelectionRespVO.setTermName(termMap.get(courseSelection.getTermId()));
        courseSelectionRespVO.setTeacherName(teacherMap.get(courseSelection.getTeacherId()));
        courseSelectionRespVO.setClassroomName(classroomMap.get(courseSelection.getClassroomId()));
        Course course = courseService.getById(courseSelection.getCourseId());
        courseSelectionRespVO.setDeptName(deptMap.get(course.getDeptId()));
        courseSelectionRespVO.setDeptId(course.getDeptId());
        return courseSelectionRespVO;


    }

    @Override
    public List<CourseSelectionRespVO> getCourseSelectionList(CourseSelectionListReqVO listReqVO) {
        Map<Long, String> courseMap = courseService.lambdaQuery()
                .like(StringUtils.isNotBlank(listReqVO.getCourseName()), Course::getCourseName, listReqVO.getCourseName())
                .list()
                .stream().collect(Collectors.toMap(Course::getId, Course::getCourseName));
        Map<Long, String> deptMap = departmentService.list().stream().collect(Collectors.toMap(Department::getId, Department::getDeptName));
        Map<Long, String> termMap = termService.list().stream().collect(Collectors.toMap(Term::getId, Term::getTermName));
        Map<Long, String> teacherMap = teacherService.lambdaQuery()
                .like(StringUtils.isNotBlank(listReqVO.getTeacherName()), Teacher::getName, listReqVO.getTeacherName())
                .list().stream().collect(Collectors.toMap(Teacher::getId, Teacher::getName));
        Map<Long, String> classroomMap = classroomService.list().stream().collect(Collectors.toMap(Classroom::getId, Classroom::getClassroomName));
        List<CourseSelection> courseSelectionList = this.lambdaQuery()
                .eq(Objects.nonNull(listReqVO.getTermId()), CourseSelection::getTermId, listReqVO.getTermId())
                .list();
        courseSelectionList =  courseSelectionList.stream()
                .filter(courseSelection -> courseMap.containsKey(courseSelection.getCourseId()) && teacherMap.containsKey(courseSelection.getTeacherId()))
                .collect(Collectors.toList());
        return courseSelectionList.stream().map(courseSelection -> {
            CourseSelectionRespVO courseSelectionRespVO = BeanUtils.toBean(courseSelection, CourseSelectionRespVO.class);
            courseSelectionRespVO.setCourseName(courseMap.get(courseSelection.getCourseId()));
            courseSelectionRespVO.setTermName(termMap.get(courseSelection.getTermId()));
            courseSelectionRespVO.setTeacherName(teacherMap.get(courseSelection.getTeacherId()));
            courseSelectionRespVO.setClassroomName(classroomMap.get(courseSelection.getClassroomId()));
            Course course = courseService.getById(courseSelection.getCourseId());
            courseSelectionRespVO.setDeptName(deptMap.get(course.getDeptId()));
            courseSelectionRespVO.setDeptId(course.getDeptId());
            return courseSelectionRespVO;
        }).collect(Collectors.toList());
    }

    @Override
    public PageResult<CourseSelectionRespVO> getCourseSelectionListPage(CourseSelectionListPageReqVO listReqVO) {
        Map<Long, String> courseMap = courseService.lambdaQuery()
                .like(StringUtils.isNotBlank(listReqVO.getCourseName()), Course::getCourseName, listReqVO.getCourseName())
                .list()
                .stream().collect(Collectors.toMap(Course::getId, Course::getCourseName));
        Map<Long, String> deptMap = departmentService.list().stream().collect(Collectors.toMap(Department::getId, Department::getDeptName));
        Map<Long, String> termMap = termService.list().stream().collect(Collectors.toMap(Term::getId, Term::getTermName));
        Map<Long, String> teacherMap = teacherService.lambdaQuery()
                .like(StringUtils.isNotBlank(listReqVO.getTeacherName()), Teacher::getName, listReqVO.getTeacherName())
                .list().stream().collect(Collectors.toMap(Teacher::getId, Teacher::getName));
        Map<Long, String> classroomMap = classroomService.list().stream().collect(Collectors.toMap(Classroom::getId, Classroom::getClassroomName));

        List<CourseSelection> courseSelectionList = this.lambdaQuery()
                .eq(Objects.nonNull(listReqVO.getTermId()), CourseSelection::getTermId, listReqVO.getTermId())
                .list();
        int size = courseSelectionList.size();
        courseSelectionList =  courseSelectionList.stream()
                .filter(courseSelection -> courseMap.containsKey(courseSelection.getCourseId()) && teacherMap.containsKey(courseSelection.getTeacherId()))
                .skip((long) (listReqVO.getPageNo() - 1) *listReqVO.getPageSize()).limit(listReqVO.getPageSize())
                .collect(Collectors.toList());

        List<CourseSelectionRespVO> courseSelectionRespVOList = courseSelectionList.stream().map(courseSelection -> {
            CourseSelectionRespVO courseSelectionRespVO = BeanUtils.toBean(courseSelection, CourseSelectionRespVO.class);
            courseSelectionRespVO.setCourseName(courseMap.get(courseSelection.getCourseId()));
            courseSelectionRespVO.setTermName(termMap.get(courseSelection.getTermId()));
            courseSelectionRespVO.setTeacherName(teacherMap.get(courseSelection.getTeacherId()));
            courseSelectionRespVO.setClassroomName(classroomMap.get(courseSelection.getClassroomId()));
            Course course = courseService.getById(courseSelection.getCourseId());
            courseSelectionRespVO.setDeptName(deptMap.get(course.getDeptId()));
            courseSelectionRespVO.setDeptId(course.getDeptId());
            return courseSelectionRespVO;
        }).collect(Collectors.toList());
        return new PageResult<>(courseSelectionRespVOList, (long) size);

    }

    @Override
    public Boolean selectCourse(Long id) {
        //获取用户
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        //获取学生信息
        Student student = studentService.lambdaQuery().eq(Student::getUserId, userId).one();
        if (student == null){
            throw new ServiceException(new ErrorCode(1000000000,"用户未登录"));
        }
        StudentCourse studentCourse = new StudentCourse();
        studentCourse.setStudentId(student.getId());
        studentCourse.setCourseSelectId(id);
        //判断课程是否已选
        if (studentCourseService.lambdaQuery()
                .eq(StudentCourse::getStudentId, student.getId())
                .eq(StudentCourse::getCourseSelectId, id).one() != null){
            throw new ServiceException(new ErrorCode(1000000000,"课程已选"));
        }
        return studentCourseService.save(studentCourse);
    }

    @Override
    public List<CourseSelectionRespVO> getCourseSelectionListByTeacherId(Long termId) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        if (userId == null){
            throw new ServiceException(new ErrorCode(1000000000,"用户未登录"));
        }
        return courseScheduleMapper.getCourseSelectionListByTeacherId(userId,termId);
    }

    @Override
    public List<CourseSelectionStudentRespVO> getCourseSelectionStudents(Long courseId) {
      return courseselectionMapper.getCourseSelectionStudents(courseId);
    }

    @Override
    public Boolean updateAndAddScore(CourseSelectionUpdateAndAddScoreReqVO updateAndAddScoreReqVO) {
        Enrollment enrollment = BeanUtils.toBean(updateAndAddScoreReqVO, Enrollment.class);
        if (enrollment.getGrade()< 0){
            throw new ServiceException(new ErrorCode(1000000000,"成绩不能小于0"));
        }
        return enrollmentService.saveOrUpdate(enrollment);
    }
}




